/*
 * Copyright (c) 2008, Xiong Yingfei, the University of Tokyo
 * All rights reserved.
 */
package ac.jp.u_tokyo.SyncLib.dictionaries;

import static ac.jp.u_tokyo.SyncLib.util.Helper.apply;
import static ac.jp.u_tokyo.SyncLib.util.Helper.areEqual;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import ac.jp.u_tokyo.SyncLib.Mod;
import ac.jp.u_tokyo.SyncLib.NullMod;
import ac.jp.u_tokyo.SyncLib.PrimMod;
import ac.jp.u_tokyo.SyncLib.SynchronizationFailedException;
import ac.jp.u_tokyo.SyncLib.util.Helper;

public class FixedKeyDynamicGet<K> extends DynamicGetBase<K>
{
	boolean _dictOverVal = true;

	public FixedKeyDynamicGet(boolean dictOverVal)
	{
		_dictOverVal = dictOverVal;
	}

	@Override
	protected Mod[] internalSync(Mod[] modifications, K oldKey,
			Map<K, Object> nullableDict, Object value)
			throws SynchronizationFailedException
	{
		if (false == modifications[1] instanceof NullMod
				&& false == modifications[1] instanceof DictMod)
			throw new SynchronizationFailedException();

		if (false == modifications[0] instanceof PrimMod
				&& false == modifications[0] instanceof NullMod)
		{
			throw new SynchronizationFailedException();
		}
		//		if (dict == null || oldKey == null)
		//			throw new SynchronizationFailedException();
		Map<K, Object> dict = nullableDict;
		if (dict == null) dict = new HashMap<K, Object>();

		Mod[] result;
		result = changeDictAndValue(modifications, oldKey, dict, value);

		if (result[1] instanceof NullMod && dict == null)
		{
			result[1] = NULLDICTMOD;
		}
		return result;
	}

	private Mod[] changeDictAndValue(Mod[] modifications, K oldKey,
			Map<K, Object> dict, Object value)
			throws SynchronizationFailedException
	{
		Mod modOnKey = modifications[0];
		final K key = apply((Mod<K>) modOnKey, oldKey);
		if (key == null) throw new SynchronizationFailedException();

		return changeDictAndValueWithFixedKey(modifications, key, dict, value,
				_dictOverVal);
	}

	@Override
	public String toString()
	{
		return "FixedDictDGet@" + hashCode();
	}
	
	
}
